package com.relytosoft.mizar.media.analyze.services.service.face.impl;


import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.relytosoft.dubhe.common.core.object.ResponseResult;
import com.relytosoft.dubhe.common.core.utils.BeanCopyUtils;
import com.relytosoft.dubhe.common.redis.utils.RedisUtil;
import com.relytosoft.mizar.media.analyze.services.service.control.ControlVerifyService;
import com.relytosoft.mizar.media.analyze.services.service.face.AyFaceAlarmService;
import com.relytosoft.mizar.media.analyze.services.service.face.AyFaceControlService;
import com.relytosoft.mizar.media.common.constant.SymbolConstants;
import com.relytosoft.mizar.media.common.entity.algo.AYFace;
import com.relytosoft.mizar.media.common.entity.algo.AYVideoSlice;
import com.relytosoft.mizar.media.common.entity.algo.AYVideoSliceCommon;
import com.relytosoft.mizar.media.common.entity.algo.AyControlFace;
import com.relytosoft.mizar.media.common.entity.pojo.dto.AyDispositionPlanDto;
import com.relytosoft.mizar.media.common.entity.pojo.dto.FaceSearchReqDto;
import com.relytosoft.mizar.media.common.entity.pojo.request.btdl.common.BtdlFaceControlReq;
import com.relytosoft.mizar.media.external.api.analyze.response.FaceSearchItemDto;
import com.relytosoft.mizar.media.external.api.analyze.service.PersonService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static com.relytosoft.mizar.media.common.constant.AyCacheConstants.CONTROL_FACE_CONDITION;
import static com.relytosoft.mizar.media.common.constant.AyCacheConstants.RAW_FACE_CONDITION;

/**
 * @author wss
 * @version 1.0
 * @date 2022/5/23 17:08
 */
@Service
public class AyFaceControlServiceImpl implements AyFaceControlService {

    protected Logger log = LoggerFactory.getLogger(this.getClass());

    @Autowired
    AyFaceAlarmService ayFaceAlarmService;
    @Autowired
    ControlVerifyService controlVerifyService;
    @Resource
    PersonService personService;

    @Override
    public Boolean rawFaceVerify(AYVideoSlice ayVideoSlice, Map<String, String> bigPic) {
        List<AYFace> ayFaces = ayVideoSlice.getFaceList().getFaceObject();
        String deviceID = ayVideoSlice.getDeviceID();
        if (ayFaces.isEmpty()) {
            return false;
        }

        Object controlJson = RedisUtil.get(RAW_FACE_CONDITION + deviceID);
        if (Objects.isNull(controlJson)) {
            return false;
        }
        List<AyDispositionPlanDto> ayDispositionPlanDtoS = JSON.parseArray(controlJson.toString(), AyDispositionPlanDto.class);
        Iterator<AyDispositionPlanDto> planDtoIterator = ayDispositionPlanDtoS.iterator();
        while (planDtoIterator.hasNext()) {
            AyDispositionPlanDto dispositionPlanDto = planDtoIterator.next();
            AYVideoSliceCommon ayVideoSliceCommon = new AYVideoSliceCommon();
            if (singleRawFaceVerify(dispositionPlanDto, ayFaces, ayVideoSliceCommon)) {
                ayFaceAlarmService.faceAlarm(dispositionPlanDto, bigPic, ayVideoSliceCommon);
                return true;
            }
        }
        return false;
    }

    @Override
    public Boolean controlFaceVerify(BtdlFaceControlReq btdlFaceControlReq) {
        String executeControlID = btdlFaceControlReq.getExecuteControlId();
        AyControlFace gaFace = btdlFaceControlReq.getgAFace();
        long markTime = gaFace.getMarkTime();
        Object controlDto = RedisUtil.get(CONTROL_FACE_CONDITION + executeControlID);
        if (Objects.isNull(controlDto)) {
            return false;
        }
        AyDispositionPlanDto ayDispositionPlanDto = JSON.parseObject(controlDto.toString(), AyDispositionPlanDto.class);
        if (!controlVerifyService.controlFrontVerify(ayDispositionPlanDto, markTime)) {
            return false;
        }
        if (controlVerifyService.controlTemplateVerify(ayDispositionPlanDto)) {
            ayFaceAlarmService.faceControlAlarm(ayDispositionPlanDto, btdlFaceControlReq);
        }
        return false;
    }

    /**
     * 单个原始人脸数据布控验证
     *
     * @param ayDispositionPlanDto
     * @param ayFaces
     * @param ayVideoSliceCommon
     * @return
     */
    private boolean singleRawFaceVerify(AyDispositionPlanDto ayDispositionPlanDto, List<AYFace> ayFaces, AYVideoSliceCommon ayVideoSliceCommon) {
        //前置验证
        if (!controlVerifyService.controlFrontVerify(ayDispositionPlanDto, System.currentTimeMillis())) {
            return false;
        }
        //布控计划验证
        if (!controlVerifyService.controlTemplateVerify(ayDispositionPlanDto)) {
            return false;
        }
        Iterator<AYFace> iterator = ayFaces.iterator();
        while (iterator.hasNext()) {
            AYFace ayFace = iterator.next();
            whitePersonVerify(ayDispositionPlanDto, ayFace, ayVideoSliceCommon);
            return true;
        }
        return false;
    }

    /**
     * 人脸白名单验证
     *
     * @param ayDispositionPlanDto
     * @param ayFace
     * @return
     */
    public Boolean whitePersonVerify(AyDispositionPlanDto ayDispositionPlanDto, AYFace ayFace, AYVideoSliceCommon ayVideoSliceCommon) {
        String whitePersonGroup = ayDispositionPlanDto.getWhitePersonGroup();

        List<String> whitePersonGroupIds;

        //白名单人员组集合id
        if (StrUtil.isNotBlank(whitePersonGroup) && !(whitePersonGroupIds = StrUtil.split(whitePersonGroup, SymbolConstants.COMMA)).isEmpty()) {
            //人脸检索调用 传入组id和特征值 阈值 判断是否在其库内
            FaceSearchReqDto faceSearchReqDto = new FaceSearchReqDto();
            faceSearchReqDto.setFeature(ayFace.getFeature());
            faceSearchReqDto.setGroupIds(whitePersonGroupIds);
            faceSearchReqDto.setThreshold(ayDispositionPlanDto.getThreshold());
            faceSearchReqDto.setTop(10000);
            ResponseResult responseResult = personService.searchPerson(faceSearchReqDto);
            List<FaceSearchItemDto> searchItemDtoS = JSON.parseArray(responseResult.getData().toString(), FaceSearchItemDto.class);
            if (searchItemDtoS.isEmpty()) {
                return false;
            }
            String faceId = ayDispositionPlanDto.getFaceId();
            Set<String> set = searchItemDtoS.stream().map(FaceSearchItemDto::getPersonId).collect(Collectors.toSet());
            if (set.contains(faceId)) {
                BeanCopyUtils.copy(ayFace, ayVideoSliceCommon);
                return true;
            }
        }
        return false;
    }

}
